import { FC, MouseEvent } from "react";
import classnames from "classnames";
import styles from "./EditCanvas.module.scss";
import { Spin } from "antd";
import { useDispatch } from "react-redux";
import {
  changeSelectedId,
  ComponentInfoType,
  moveComponent,
} from "@/store/componentsReducer";
import useGetComponentInfo from "@/hooks/useGetComponentInfo";
import { getComponentConfByType } from "@/components/QuestionComponents";
import useBindCanvasKeyPress from "@/hooks/useBindCanvasKeyPress";
import SortableContainer from "@/components/DragSortable/SortableContainer";
import SortableItem from "@/components/DragSortable/SortableItem";

type PropsType = {
  loading: boolean;
};

const EditCanvas: FC<PropsType> = (props) => {
  const { loading } = props;
  const { componentList, selectedId } = useGetComponentInfo();
  const dispatch = useDispatch();

  useBindCanvasKeyPress();

  if (loading) {
    return (
      <div style={{ textAlign: "center", marginTop: "30px" }}>
        <Spin />
      </div>
    );
  }

  const handleClick = (e: MouseEvent, id: string) => {
    e.stopPropagation();
    dispatch(changeSelectedId(id));
  };

  const generateComponent = (componentInfo: ComponentInfoType) => {
    const { type, props } = componentInfo;

    const config = getComponentConfByType(type);

    if (!config) return null;

    const { Component } = config;

    return <Component {...props} />;
  };

  const componentListWithId = componentList.map((c) => ({ ...c, id: c.fe_id }));

  const handleDragEnd = (oldIndex: number, newIndex: number) => {
    dispatch(moveComponent({ oldIndex, newIndex }));
  };

  return (
    <div className={styles.canvas}>
      <SortableContainer items={componentListWithId} onDragEnd={handleDragEnd}>
        {componentList
          .filter((c) => !c.isHidden)
          .map((c) => {
            const { fe_id, isLocked } = c;

            const wrapperDefaultClassName = styles["component-wrapper"];
            const selectedClassName = styles["selected"];
            const lockedClassName = styles["locked"];
            const wrapperClassName = classnames({
              [wrapperDefaultClassName]: true,
              [selectedClassName]: fe_id === selectedId,
              [lockedClassName]: isLocked,
            });

            return (
              <SortableItem id={fe_id} key={fe_id}>
                <div
                  className={wrapperClassName}
                  onClick={(e) => handleClick(e, fe_id)}
                >
                  <div className={styles.component}>{generateComponent(c)}</div>
                </div>
              </SortableItem>
            );
          })}
      </SortableContainer>
    </div>
  );
};

export default EditCanvas;
